﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.LinkLabel;

namespace WinFormsApp1
{
    public partial class TableWithKey : UserControl
    {
        private string m_fileName;
        private DataTable m_dataTable;

        public TableInfo TableData = new TableInfo();

        public TableWithKey(DataTable dt, string fileName)
        {
            m_fileName = fileName;
            m_dataTable = dt;
            TableData.RefDataTable = dt;

            InitializeComponent();
        }
        public void LoadData()
        {
            TableData.TableName = Path.GetFileNameWithoutExtension(m_fileName);

            var columnNameFile = Path.ChangeExtension(m_fileName, ".clm");
            string columnName = Path.GetFileNameWithoutExtension(m_fileName);

            if (File.Exists(columnNameFile))
            {
                var lines = File.ReadAllLines(columnNameFile);
                foreach (string line in lines)
                {
                    var ks = line.Split(',');
                    DataColumInfo columInfo = new DataColumInfo()
                    {
                        TableName = columnName,

                        ColumnName = ks[0],
                        ColumnType = ks[1],
                        ColumnLength = int.Parse(ks[2])
                    };
                    columInfo.RefExcel = TableData;
                    TableData.Columns.Add(columInfo);
                }
            }
            else
            {
                int columnIndex = 0;
                foreach (DataColumn column in m_dataTable.Columns)
                {
                    var vlen = m_dataTable.Rows[0].ItemArray[columnIndex].ToString().Length;
                    DataColumInfo columInfo = new DataColumInfo()
                    {
                        TableName = columnName,
                        ColumnName = column.ColumnName,
                        ColumnType = "无类别",
                        ColumnLength = vlen
                    };
                    columInfo.RefExcel = TableData;
                    TableData.Columns.Add(columInfo);

                    columnIndex++;
                }
            }

            var entityFileName = Path.ChangeExtension(m_fileName, ".ent");
            if (File.Exists(entityFileName))
            {
                var rows = File.ReadAllLines(entityFileName);
                for (var i = 0; i < rows.Length; i++)
                {
                    var rs = rows[i];
                    TableData.EntityColumns.Add(new EntityNaming(rows[i]));
                }
            }
        }
        /// <summary>
        /// 保存列信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            var columnNameFile = Path.ChangeExtension(m_fileName, ".clm");
            var Columns = TableData.Columns;
            using (StreamWriter stream = File.CreateText(columnNameFile))
            {
                for (var i = 0; i < Columns.Count; i++)
                {
                    stream.WriteLine(Columns[i].ColumnName + "," + Columns[i].ColumnType + "," + Columns[i].ColumnLength);
                }
                stream.Close();
            }
            MessageBox.Show("保存列成功");
        }
        private void TableWithKey_Load(object sender, EventArgs e)
        {
            this.dataGridView1.DataSource = m_dataTable;

            TableData.RefDataTable = m_dataTable;
            var Columns = TableData.Columns;
            var EntityColumns = TableData.EntityColumns;

            for (var i = 0; i < Columns.Count; i++)
            {
                var column = Columns[i];
                ListViewItem lvi = new ListViewItem(column.ColumnName);
                lvi.SubItems.Add(column.ColumnType);
                lvi.SubItems.Add(column.ColumnLength.ToString());
                lvi.Tag = column;

                this.listView1.Items.Add(lvi);
            }

            for (var i = 0; i < EntityColumns.Count; i++)
            {
                var vi = EntityColumns[i].ToString();
                ListViewItem lv = new ListViewItem(vi);
                lv.Tag = EntityColumns[i];
                this.listView2.Items.Add(lv);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.listView1.SelectedItems.Count == 0) return;
            ListViewItem lvi = this.listView1.SelectedItems[0];

            DataColumInfo columInfo = lvi.Tag as DataColumInfo;
            FormColumnSetting formColumnSetting = new FormColumnSetting(columInfo);
            formColumnSetting.StartPosition = FormStartPosition.CenterScreen;
            if (formColumnSetting.ShowDialog() == DialogResult.OK)
            {
                lvi.SubItems[1].Text = columInfo.ColumnType;
                lvi.SubItems[2].Text = columInfo.ColumnLength.ToString();
            }
        }

        private int m_lastSelectedColumIndex = -1;
        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            var columnName = e.ColumnIndex;
            m_lastSelectedColumIndex = columnName;

            for (var i = 0; i < this.listView1.Items.Count; i++)
            {
                this.listView1.Items[i].Selected = false;
            }
            this.listView1.Items[columnName].Selected = true;
            this.listView1.Items[columnName].EnsureVisible();

            if (e.Button == MouseButtons.Right)
            {
                var len = 0;
                for (var i = 0; i <= columnName; i++)
                {
                    len += dataGridView1.Columns[i].Width;
                }
                len -= dataGridView1.HorizontalScrollingOffset;
                this.contextMenuStrip1.Show(dataGridView1, len, 32);
            }
        }

        /// <summary>
        /// 要作为实体列，那么内容一定不能存在相同的
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 设置实体列ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<string> items = new List<string>();
            for (var i = 0; i < m_dataTable.Rows.Count; i++)
            {
                var v = m_dataTable.Rows[i][m_lastSelectedColumIndex];
                if (v == null)
                {
                    MessageBox.Show("存在空数据的不能作为实体列.");
                    return;
                }
                var vs = v.ToString();
                items.Add(vs);
            }
            items.Sort();
            for (var i = items.Count - 1; i > 0; i--)
            {
                if (items[i] == items[i - 1])
                {
                    MessageBox.Show("相同数据的不能作为实体列.");
                    return;
                }
            }
            var lvi1 = this.listView1.Items[m_lastSelectedColumIndex];
            var column = lvi1.Tag as DataColumInfo;

            for (var i = 0; i < TableData.EntityColumns.Count; i++)
            {
                if (TableData.EntityColumns[i].ColumnName == column.ColumnName)
                {
                    return;
                }
            }


            ListViewItem lv = new ListViewItem(column.ColumnName);
            var rc = new EntityNaming() { ColumnName = column.ColumnName };
            TableData.EntityColumns.Add(rc);
            lv.Tag = rc;
            this.listView2.Items.Add(lv);

            SaveEntityColumns();
        }


        #region 实体列
        private void button4_Click(object sender, EventArgs e)
        {
            if (listView2.SelectedItems.Count == 0) return;
            var columnName = listView2.SelectedItems[0].Text;
            for (var i = 0; i < TableData.EntityColumns.Count; i++)
            {
                if (TableData.EntityColumns[i].ToString() == columnName)
                {
                    TableData.EntityColumns.RemoveAt(i);
                }
            }

            listView2.Items.Remove(listView2.SelectedItems[0]);
            SaveEntityColumns();
        }
        private void SaveEntityColumns()
        {
            var columnNameFile = Path.ChangeExtension(m_fileName, ".ent");
            using (StreamWriter stream = File.CreateText(columnNameFile))
            {
                for (var i = 0; i < this.listView2.Items.Count; i++)
                {
                    var ec= this.listView2.Items[i].Tag as EntityNaming;
                    if (ec == null)
                    {
                        continue;
                    }
                    stream.WriteLine(ec.ToString());
                }
                stream.Close();
            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
            SaveEntityColumns();
            MessageBox.Show("保存列成功");
        }
        private void button5_Click(object sender, EventArgs e)
        {
            if (listView2.SelectedItems.Count == 0)
            {
                MessageBox.Show("没有选择实体列");
                return;
            }

            FormEntityColumnEditor from = new FormEntityColumnEditor();
            from.SelectedEntityColumn= listView2.SelectedItems[0].Tag as EntityNaming;
            from.StartPosition = FormStartPosition.CenterScreen;
            if(from.ShowDialog()== DialogResult.OK)
            {
                listView2.SelectedItems[0].Text = from.SelectedEntityColumn.ToString();
                SaveEntityColumns();
            }
        } 
        #endregion

        #region 数据脱敏
        private Random m_random;
        private void 身份证重编ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_random = new Random(System.Environment.TickCount);
            ToMinItem(out int recordCount, out int tableCount);
            MessageBox.Show(string.Format("OK,完成对{0}个表，共计{1}条记录进行处理", tableCount, recordCount));
        }

        private void 电话号码重编ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_random = new Random(System.Environment.TickCount);
            ToMinItem(out int recordCount, out int tableCount);
            MessageBox.Show(string.Format("OK,完成对{0}个表，共计{1}条记录进行处理", tableCount, recordCount));
        }

        private void 姓名重编ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_random = new Random(System.Environment.TickCount);
            ToMinItem(out int recordCount, out int tableCount);
            MessageBox.Show(string.Format("OK,完成对{0}个表，共计{1}条记录进行处理", tableCount, recordCount));
        }
        private void ToMinItem(out int recordCount, out int tableCount)
        {
            //当前表的身份证
            var stringLength = 0;
            List<string> allIDs = GetColumnData(m_lastSelectedColumIndex);
            stringLength = allIDs[0].Length;

            var otherTables = (this.ParentForm as Form1).AllTables;
            int[] selColumns = new int[otherTables.Count];

            List<TuominItem> allGlobalIds = new List<TuominItem>();

            tableCount = 0;
            for (var j = 0; j < otherTables.Count; j++)
            {
                var columnIndex = otherTables[j].FindColumnByData(allIDs, out int rowIndex);
                if (columnIndex == -1) continue;
                tableCount++;
                selColumns[j] = columnIndex;
                var otherIds = otherTables[j].GetColumnDataOfDetail(columnIndex);
                allGlobalIds.AddRange(otherIds);
            }
            recordCount = allGlobalIds.Count;

            Dictionary<string, string> oldNewMatch = new Dictionary<string, string>();
            for (var i = 0; i < allGlobalIds.Count; i++)
            {
                string replaceName = "";
                if (oldNewMatch.ContainsKey(allGlobalIds[i].Data))
                {
                    replaceName = oldNewMatch[allGlobalIds[i].Data];
                }
                else
                {
                    replaceName = RandString(stringLength, stringLength > 5, stringLength < 5);
                    oldNewMatch[allGlobalIds[i].Data] = replaceName;
                }
                allGlobalIds[i].SetVale(replaceName);
            }
            for (var j = 0; j < otherTables.Count; j++)
            {
                otherTables[j].dataGridView1.DataSource = otherTables[j].m_dataTable;
            }
        }
        private List<string> GetColumnData(int columnIndex)
        {
            List<string> allIDs = new List<string>();
            for (var i = 0; i < m_dataTable.Rows.Count; i++)
            {
                allIDs.Add(m_dataTable.Rows[i][columnIndex].ToString());
            }
            return allIDs;
        }
        private List<TuominItem> GetColumnDataOfDetail(int columnIndex)
        {
            List<TuominItem> allIDs = new List<TuominItem>();
            for (var i = 0; i < m_dataTable.Rows.Count; i++)
            {
                TuominItem tuominItem = new TuominItem()
                {
                    Table = m_dataTable,
                    ColumnIndex = columnIndex,
                    RowIndex = i,
                    Data = m_dataTable.Rows[i][columnIndex].ToString()
                };
                allIDs.Add(tuominItem);
            }
            return allIDs;
        }
        /// <summary>
        /// 查询表内容
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public int FindColumnByData(List<string> items, out int rowIndex)
        {
            for (var i = 0; i < m_dataTable.Columns.Count; i++)
            {
                for (var j = 0; j < m_dataTable.Rows.Count; j++)
                {
                    var str = m_dataTable.Rows[j][i].ToString();
                    if (items.Contains(str))
                    {
                        rowIndex = j;
                        return i;
                    }
                }
            }
            rowIndex = -1;
            return -1;
        }
        // <summary>
        /// 查询表内容,行列
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public List<int[]> FindColumnByData(string strToFind)
        {
            List<int[]> res = new List<int[]>();
            for (var i = 0; i < m_dataTable.Columns.Count; i++)
            {
                for (var j = 0; j < m_dataTable.Rows.Count; j++)
                {
                    var str = m_dataTable.Rows[j][i].ToString();
                    if (str.IndexOf(strToFind) >= 0)
                    {
                        res.Add(new int[] { j, i });
                    }
                }
            }
            return res;
        }
        class TuominItem
        {
            public DataTable Table { get; set; }
            public int ColumnIndex { get; set; }
            public int RowIndex { get; set; }
            public string Data { get; set; }

            public void SetVale(string str)
            {
                Table.Rows[RowIndex][ColumnIndex] = str;
            }
        }

        string[] fiName = new string[]{"王","李","张","刘","陈","杨","黄","赵","吴","周","徐","孙","马","朱","胡","郭",
        "何","林","高","罗","郑","梁","谢","宋","唐","许","邓","韩","冯","曹","彭","曾",
        "肖","田","董","潘","袁","蔡","蒋","余","于","杜","叶","程","魏","苏","吕","丁",
        "任","卢","姚","沈","钟","姜","崔","谭","陆","汪","范","廖","石","金","韦","贾",
        "夏","付","方","邹","熊","白","孟","秦","邱","侯","江","尹","薛","闫","雷","龙",
        "黎","史","陶","贺","毛","段","郝","顾","龚","邵","覃","武","钱","戴","严","莫",
        "孔","常","汤","赖","萧","傅","阎","包","康","伍","施","万","洪","庞","樊","季",
        "庄","殷","温","倪","翟","申","向","齐","乔","文","安","易","颜","牛","岳","顔",
        "简","骆","毕","章","鲁","关","葛","柳","俞","聂","蓝","祝","柴","纪","焦","祁" };
        string[] nName = "裘心,杜霞,焦禄,王爽,萧通,纪迎,钱河,谭桃,蒋媚,伊婧,梅衡,高旻,罗莲,束源,翁娴,庞丹,幸音,马郁,费岭,俞育,蒙知,韶焰,田炯,惠争,石深,白攀,范赛,叶联,井鸽,郭怀,翁麒,黎滢,周江,陈钧,蓬辰,巫辉,杭俏,严霞,毕广,皮婵,邹萱,房创,褚剑,赵珊,钱毓,孔暖,田喜,陆展,伍瑛,翁谨,房淑,傅焕,葛霓,夏星,经婉,江晏,颜川,农领,焦珏,花壮,杭恋,韦鹃,林莎,姬育,梅嵘,松俐,宗巧,孟旭,戴飚,龙笛,刘品,娄真,翁银,舒杨,金子,宫里,巫艺,石傲,程优,沈汉,仲芬,蓬垣,樊剑,严风,葛田,田倩,赵名,班营,喻海,屈聪,邱苏,阮嫒,祖洋,裴月,韩彤,谭卉,乔焕,罗润,水舜,解娣,朱原,何心,齐泉,刁翊,乔知,徐歌,乔沙,萧鸽,何秋,尚泰,汤亭,左英,施勋,钱舒,蔡会,明尤,凤鸿,邴舒,滕筝,许炜,施建,石妍,岑花,姜弛,牧蔚,侯多,邢蜜,曹璟,龚媚,纪花,祁杰,乌壮,邹翊,朱博,武歌,盛天,农强,尚滢,莫京,刘闯,宁令,姬秦,裴铃,水爽,张迅,苏生,毛朦,王铭,喻焕,严沙,芮吉,花灿,詹信,董盈,金娥,彭牧,羿亚,倪惟,岑宾,魏彬,申泉,鲍金,邵琦,乌威,马衡,夏霏,霍梁,魏兵,管熙,徐标,褚翠,余霄,徐丰,戚苹,时文,王举,姜迁,虞迁,卫影,尤澎,邵将,程青,白心,许义,冯星,武娓,童筝,吴柳,农宁,惠祯,奚童,鲍继,万研,韶翔,阮眉,石晨,伏龙,滕娣,伊栩,成鹰,包霏,鲁珑,倪同,何苓,巫韶,郁晗,段贞,许漪,滑焱,韩劲,韩敏,杭沙,宋延,劳琛,赖迅,咎响,虞罡,刁玲,姚戈,盛名,颜祺,井俊,阮潜,高韶,滕宜,谢淑,侯骏,窦琦,翁韵,裴瑜,童昕,姚炯,阮沫,幸鸿,仲柳,羿洋,颜江,柏菲,阮千,何珏,姚津,卓敏,李臣,叶晗,贺荟,徐意,常攀,蔡伟,经芝,苗将,张诺,方忆,邴恺,钟泓,莫君,惠利,江俐,魏嘉,昌秀,韶鹃,常茉,廉征,倪瑜,魏祺,章妙,盛惠,伏延,羿冉,姬笑,袁萌,房礼,薛河,唐丽,蓬漪,董行,薄曦,汤琴,尹凝,解灵,嵇瑶,曹运,庞竹,唐队,史如,尚韦,蓬洲,柯梁,符千,朱微,石沙,胡辉,劳颖,吉啸,段季,宁莉,窦颜,嵇玥,江汉,滕昊,卓竹,曹桢,侯路,赵苓,史盛,明彤,蓬戈,解钥,苏沙,屈州,经嫚,解众,刁金,纪方,符讳,徐溢,穆栋,焦灏,管殉,齐唯,高焘,温然,顾钦,童达,俞杏,宗苹,尤谨,计筱,巫麒,雷妹,瞿钧,费琰,甄梦,董皓,冯宝,王宙,井竹,晏睿,杭松,陈沫,管云,余青,宣默,许喻,苗蔚,俞葵,贾遥,钟广,晏元,费知,巫璋,李姬,常溪,郑洵,罗娅,包溪,贾晔,樊丹,沈栋,温飙,姜咏,方驰,尹伊,周玫,鲁桢,葛惠,戴跃,金炯,裴婉,明思,宁蕴,邓煦,薛煦,邹敏,常剑,鲁含,尹素,范喜,邢妹,徐炯,俞逸,章菱,贡谦,樊芸,申姣,林幸,柳旎,姬轲,嵇畏,尹梦,舒蔚,邬亚,娄东,翁澎,魏亭,姬鲁,娄玮,程园,秋举,邴颜,滑琴,常腾,胡轩,申允,牧璋,吉海,单鸿,钱臻,廉真,水榕,俞谊,柳麒,祝锦,谢功,滕樱,经雪,窦漫,符芸,嵇展,曹强,陈爽,云博,谢靓,尹圣,支妹,程为,赖沛,常达,秋闻,苗恋,乔靓,邢洁,农礼,明如,裴健,吕臣,黎坤,戚京,宫俪,殷楷,娄举,常肠,石翊,杨剑,富言,殷娴,温璞,蓬荔,廉尉,盛讳,蒋玥,田运,钱贞,尹希,邢轩,陈榕,莫汝,冯漪,卫山,滑顺,水宜,葛洋,崔灏,缪桢,颜栋,马天,姚劫,左嫚,强杏,苗苹,余千,翟帆,鲁想,孙凡,凌鹰,申如,曹音,汤曼,惠暖,强澜,陈俭,夏开,尤娜,平元,伏普,洪冉,解湛,芮为,祁燃,苏舰,颜澎,钟韶,童锦,甄倩,潘诚,牧赫,钟力,费碧".Split(',');

        private string RandString(int length, bool isNum, bool isChs)
        {
            StringBuilder sb = new StringBuilder();

            if (isNum)
            {
                sb.Append("9");
                for (var i = 1; i < length; i++)
                {
                    sb.Append(m_random.Next(0, 10));
                }
                return sb.ToString();
            }

            if (isChs)
            {
                return fiName[m_random.Next(0, fiName.Length)] + "一" + nName[m_random.Next(0, nName.Length)].Substring(1);
            }
            return "";
        }
        #endregion

       
    }
}
